#include "networkclient.h"
#include <QDataStream>
#include <QDebug>

NetworkClient::NetworkClient(QObject *parent) : QObject(parent),
    m_defaultHost("127.0.0.1"),
    m_defaultPort(8888) {
    m_socket = new QTcpSocket(this);
    
    connect(m_socket, &QTcpSocket::connected, this, &NetworkClient::onConnected);
    connect(m_socket, &QTcpSocket::disconnected, this, &NetworkClient::onDisconnected);
    connect(m_socket, &QTcpSocket::readyRead, this, &NetworkClient::onReadyRead);
    connect(m_socket, QOverload<QAbstractSocket::SocketError>::of(&QTcpSocket::error),
            this, &NetworkClient::onError);
}

NetworkClient::~NetworkClient() {
    disconnectFromServer();
}

NetworkClient& NetworkClient::instance() {
    static NetworkClient instance;
    return instance;
}

void NetworkClient::setDefaultServer(const QString& host, quint16 port) {
    m_defaultHost = host;
    m_defaultPort = port;
}

bool NetworkClient::connectToServer(const QString& host, quint16 port) {
    if (m_socket->state() == QAbstractSocket::ConnectedState) {
        return true;
    }
    
    m_socket->connectToHost(host, port);
    return m_socket->waitForConnected(3000);
}

void NetworkClient::disconnectFromServer() {
    if (m_socket->state() == QAbstractSocket::ConnectedState) {
        m_socket->disconnectFromHost();
    }
}

bool NetworkClient::isConnected() const {
    return m_socket->state() == QAbstractSocket::ConnectedState;
}

void NetworkClient::sendRequest(MessageType type, const QJsonObject& data) {
    if (!isConnected()) {
        emit errorOccurred("未连接到服务器");
        return;
    }
    
    QByteArray message = Protocol::createMessage(type, data);
    m_socket->write(message);
    m_socket->flush();
}

void NetworkClient::onConnected() {
    qDebug() << "已连接到服务器";
    emit connected();
}

void NetworkClient::onDisconnected() {
    qDebug() << "已断开与服务器的连接";
    emit disconnected();
}

void NetworkClient::onReadyRead() {
    m_buffer.append(m_socket->readAll());
    
    while (m_buffer.size() >= 4) {
        QDataStream stream(&m_buffer, QIODevice::ReadOnly);
        stream.setVersion(QDataStream::Qt_5_0);
        
        quint32 messageSize;
        stream >> messageSize;
        
        if ((quint32)m_buffer.size() < 4 + messageSize) {
            break;
        }
        
        QByteArray messageData = m_buffer.mid(4, messageSize);
        m_buffer.remove(0, 4 + messageSize);
        
        MessageType type;
        QJsonObject data;
        if (Protocol::parseMessage(messageData, type, data)) {
            emit messageReceived(type, data);
        }
    }
}

void NetworkClient::onError(QAbstractSocket::SocketError error) {
    Q_UNUSED(error);
    emit errorOccurred(m_socket->errorString());
    qDebug() << "网络错误:" << m_socket->errorString();
}

